package c03数据类型和运算符;

public class 基本类型和引用类型的转换问题 {

	public static void main(String[] args) {

		//基本类型可以分为数值型（char可以转换为整型）和布尔型。两种类型不可以直接互相转换！：
//		boolean b=(boolean)0;//编译错误！

		//数值型按从小到大可以分为@1和@2两支，可以拆为以下几段：
		//@1 char<int; @2 byte<short<int;  int<long; @@ long<float;  float<double; 
		//1、在上面的每条分支中，左边的变量可以直接赋给右边的；右边赋给左边则需要强制类型转换！
		//2、注意long是小于float的！可以理解为整形都小于浮点型。
		//3、char与byte、short之间的转换最好强制类型转换，不然很容易出错，可见下面例子：

		byte bt = 0;
		short s = 0;
		char c = 'a';
		int i = 0;
		long l = 0;
		float f = 0;
		double d = 0;

		//char与byte、short的常量或变量之间的转换的特殊性：
		bt = 'a';//正确！
		s = '\u0018';//正确！
		bt = '\u0018';//正确！
//		bt='\u0128';//编译错误，提示转换为bt！
		c = '\u0128';//正确！
		c = 65535;//只要范围在0~65535之间的整形都可以直接赋给char！
//		c=65536;//超出这范围之后就会编译错误！
//		c=-1;//超出这范围之后就会编译错误！

		bt = (byte) c;//变量就一定要强制类型转换！
		s = (short) c;//变量就一定要强制类型转换！
		c = (char) bt;//变量就一定要强制类型转换！
		c = (char) s;//变量就一定要强制类型转换！

		i = c;
		l = c;
		f = c;
		d = c;

		l = (long) f;//因为l<f，所以必须强制类型转换！
		f = l;

		//基本类型和包装类型之间的转换：
		//基本类型装箱到包装类时要对类型，不然要强制类型转换！
		Integer I = new Integer(0);
//		I=bt;//编译错误！提示强制转换到int。
//		I=s;//编译错误！提示强制转换到int。
//		I=c;//编译错误！提示强制转换到int。
		I = i;
//		I=l;//编译错误！提示强制转换到int。
//		I=f;//编译错误！提示强制转换到int。
//		I=d;//编译错误！提示强制转换到int。

		//包装类拆箱到基本类型时可以拆给对应类型或者更大的类型！
		i = I;
		l = I;
		f = I;
		d = I;//@@I只能拆箱给int类型或更大的类型！
//		bt=I;//编译错误！
		i = I;

		//其他引用类型之间的转换：
		Object o = new Object();
//		o=I;//向上转型，不需要强制类型转换。上，即继承树的根（父类）方向。
//		I=(Integer) o;//向下转型，必须强制类型转换！但并非所有父类对象都可以转换为子类对象！例如把上面一行代码
		//注释掉，可以通过编译，但是运行时就会引发ClassCastException异常！
		//这是因为运行时o并不知道I是自己的子类！因此向下转型时最后结合instanceof来使用：

		//语法【实例 instanceof 某类】，判断的是实例是不是某类的（子）实例。
		if (o instanceof Integer) {
			I = (Integer) o;
			System.err.println("转换成功！");
		} else {
			System.err.println("转换失败！");
		}
		//关于instanceof的详细使用方法可见：c05面向对象.使用的注意事项.java 。
	}

}
